<?php
namespace app\api\controller\kuerp\order;

use app\api\library\kuerp\Auth;
use app\common\controller\Api;
use app\api\library\kuerp\Wechat;
use app\api\model\kuerp\UserOauth;
use think\Db;
use app\common\library\Sms;
use fast\Random;
class Weixin extends Api
{
    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';

    /**
     * 获取微信小程序session_key
     *
     * @param string  $code      加密code
     * @param boolean $autoLogin 是否自动登录(需已注册会员)
     */
    public function getWxMiniProgramSessionKey()
    {
        $post = $this->request->post();
        $autoLogin = $post['autoLogin'];
        $wechat = new Wechat('wxMiniProgram');
        $decryptSession = $wechat->code($post['code']);
        if (!isset($decryptSession['session_key'])) {
            $this->error($decryptSession['errmsg'],'',401);
        }
        \think\Cache::set($decryptSession['session_key'], $decryptSession,
            24 * 3600 * 31); // 强制31天过期
        $userOauth = UserOauth::get([
            'provider' => 'Wechat',
            'platform' => 'wxMiniPrograms',
            'openid'   => $decryptSession['openid'],
            'user_id'  => ['>',0]
        ]);
        $userOauthInfo = Db::name('kuerp_user_oauth')->where([
            'provider' => 'Wechat',
            'platform' => 'wxMiniPrograms',
            'openid'   => $decryptSession['openid'],
            'user_id'  => ['>',0]
        ])->find();
        if($userOauthInfo){
            $user = Db::name('kuerp_user')->where(['id'=>$userOauthInfo['user_id']])->find();
            if(empty($user)){
                Db::name('kuerp_user_oauth')->where(['id'=>$userOauthInfo['id']])->delete();
                $userOauth = [];
            }elseif($user['status']=='hidden'){
                $this->error('账户已禁用','',401);
            }
        }
        if ($userOauth && $userOauthInfo) {
            $userOauth->save(['session_key' => $decryptSession['session_key']]);
        }
        if ($autoLogin && $userOauth) {
            $auth = new Auth();
            $ret = $auth->direct($userOauthInfo['user_id']);
            if ($ret) {
                $token = $auth->getToken();
                $this->success('登陆成功', [
                    'token'       => $token,
                    'session_key' => $decryptSession['session_key'],
                    'openid'      => $decryptSession['openid']
                ],'200');
            } else {
                $this->error($auth->getError(),'',500);
            }
        }
        $this->success('', $decryptSession,200);
    }

    /**
     * 微信小程序登录
     *
     * @param string  $session_key   session_key
     * @param string  $signature     校验签名
     * @param string  $iv            解密向量
     * @param string  $encryptedData 需解密完整用户信息
     * @param boolean $refresh       重新获取或刷新最新的用户信息 (用户头像失效或微信客户端修改昵称等情况)
     */
    public function wxMiniProgramOauth()
    {
        $post = $this->request->post();

        $wechat = new Wechat('wxMiniProgram');
        $decryptSession = \think\Cache::get($post['session_key']);
        if (!$decryptSession || !isset($decryptSession['openid'])) {
            $this->error('未获取到登录依据,请重试',[],205);
        }
        $decryptUserInfo = $wechat->decryptData($post['session_key'],
            $post['iv'],
            $post['encryptedData']); // 客户端传值数据都不可信，需服务端解密用户信息
        $decryptUserInfo = array_merge($decryptUserInfo,
            $decryptSession);
        //组装decryptData
        $decryptData = array_change_key_case($decryptUserInfo,
            CASE_LOWER);
        if (empty($decryptData['openid'])) {
            $this->error('code错误,请重试',[],206);
        }
        $decryptData['headimgurl'] = $decryptData['avatarurl'];
        $decryptData['sex'] = $decryptData['gender'];
        $decryptData['session_key'] = $post['session_key'];
        $result = $this->oauthLoginOrRegisterOrBindOrRefresh($post['event'],
            $decryptData, 'wxMiniPrograms', 'Wechat');
        if($result['status']==0){
            $this->error($result['msg'],'',500);
        }else if($result['status']==2){
            $this->error('请绑定账户',['openid'=>$result['openid']],209);
        }else{
            $token = $result['token'];
        }

        if ($token) {
            $auth = \app\api\library\kuerp\Auth::instance();
            $auth->setAllowFields([
                'id',
                'username',
                'nickname',
                'mobile',
                'avatar',
                'score',
                'birthday',
                'money',
                'binding',
                'group_id'
            ]);
            $auth->init($token);
            $data = $auth->getUserinfo();
            $data['avatar'] = $data['avatar'] ? cdnurl($data['avatar'], true) : '';
            $this->success(__('登陆成功'), ['userinfo' => $data],200);
        } else {
            $auth = new Auth();
            $this->error($auth->getError(),[],500);
        }
    }

    /**
     * 绑定
     */
    public function bind()
    {
        $captcha = $this->request->post("captcha");
        $mobile = $this->request->post("mobile");
        $ret = Sms::check($mobile, $captcha, 'changemobile');
        if (!$ret) {
            $this->error(__('验证码错误'),'',500);
        }else{

            $auth = new Auth();
            $token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));
            $auth->init($token);

            $user = $auth->getUserinfo();
            if(!isset($user['id'])){
                $this->error('请先登陆','',250);
            }
            $data['user_id'] = $user['id'];

            $user = Db::name('kuerp_user')->where(['id'=>$data['user_id']])->find();
            if(empty($user)){
                $this->error('未找到相关用户','',500);
            }else if($user['binding']!=2){
                $this->error('此用户已绑定','',500);
            }else{
                $customer = Db::name('kuerp_customers')->where(['customer_mobile'=>$mobile])->find();
                if(empty($customer)){
                    $this->error('此手机号尚未成为客户，不可绑定','',500);
                }
                $status = Db::name('kuerp_user')->where(['id'=>$user['id']])->update([
                    'binding'=>'1',
                    'customers_id'=>$customer['id'],
                    'username'=>$mobile,
                    'mobile'=>$mobile
                ]);
                if ($status){
                    $auth->direct($user['id']);
                    $this->success(__('绑定成功'), ['token'=>$auth->getToken()],200);
                }else{
                    $this->error('绑定失败','',500);
                }
            }
        }
    }

    /**
     * 第三方登录或自动注册
     *
     * @param string $event       事件:login=登录, refresh=更新账号授权信息, bind=绑定第三方授权
     * @param array  $decryptData 解密参数
     * @param string $platform    平台名称
     * @param string $provider    厂商名称
     * @param int    $keeptime    有效时长
     */
    private function oauthLoginOrRegisterOrBindOrRefresh(
        $event,
        $decryptData,
        $platform,
        $provider,
        $keeptime = 0
    ) {
        $oauthData = $decryptData;
        $oauthData = array_merge($oauthData, [
            'provider' => $provider,
            'platform' => $platform,

        ]);
        if ($platform === 'wxMiniPrograms' || $platform === 'App') {
            $oauthData['expire_in'] = 7200;
            $oauthData['expiretime'] = time() + 7200;
        }
        $userOauth = UserOauth::where([
            'openid'  => $decryptData['openid']
        ])->where('platform', $platform)->where('provider', $provider)->find();
        $auth = new Auth();
        switch ($event) {
            case 'login':               // 登录(自动注册)
                if (!$userOauth) {      // 没有找到第三方登录信息 创建新用户
                    //默认创建新用户
                    $oauthData['logintime'] = time();
                    $oauthData['logincount'] = 1;
                    // 判断是否有unionid 并且已存在oauth数据中
                    $oauthData['user_id'] = 0;
                    $oauthData['createtime'] = time();
                    $userOauthInfo = Db::name('kuerp_user_oauth')->where([
                        'provider' => 'Wechat',
                        'platform' => 'wxMiniPrograms',
                        'openid'   => $oauthData['openid'],
                    ])->find();
                    if(empty($userOauthInfo)){
                        UserOauth::strict(false)->insert($oauthData);
                    }

                    $salt = Random::alnum();
                    $newpassword = $auth->getEncryptPassword(123456, $salt);
                    $register = $auth->register($oauthData['openid'],$oauthData['headimgurl'],$oauthData['nickname'],$newpassword);
                    if($register){
                        $user_id = Db::name('kuerp_user')->where(['username'=>$oauthData['openid']])->value('id');
                        if($user_id){
                            UserOauth::where([
                                'openid'  => $decryptData['openid']
                            ])->where('platform', $platform)->where('provider', $provider)->update(['user_id'=>$user_id]);
                        }
                    }
                } else {
                    // 找到第三方登录信息，直接登录
                    $user_id = $userOauth->user_id;
                    if ($user_id && $auth->direct($user_id) && $auth->getUser()){       // 获取到用户
                        $oauthData['logincount'] = $userOauth->logincount + 1;
                        $oauthData['logintime'] = time();
                        $userOauth->allowField(true)->save($oauthData);
                        $auth->getUser()->save(['nickname' => $oauthData['nickname'],'avatar' => $oauthData['headimgurl']]);
                    } else {         // 用户已被删除 重新执行登录
                        // throw \Exception('此用户已删除');
                        $userOauth->delete();
                        $this->oauthLoginOrRegisterOrBindOrRefresh($event,
                            $decryptData, $platform, $provider);
                    }
                }
                break;
        }
        if ($auth->getUser()) {
            $this->setUserVerification($auth->getUser(), $provider,
                $platform);
            return ['status'=>1,'token'=>$auth->getToken(),'openid'=>''];
        }
        return ['status'=>0,'msg'=>'登录失败','openid'=>''];
    }

    /**
     * 第三方用户授权信息
     */
    public function thirdOauthInfo()
    {
        $auth = new Auth();
        $user = $auth->getUser();
        $platform = request()->header('platform');
        $userOauth = UserOauth::where([
            'platform' => $platform,
            'user_id'  => $user->id
        ])->field('headimgurl, nickname')->find();
        $this->success('获取成功', $userOauth);
    }


    /**
     * 解除绑定
     */
    public function unbindThirdOauth()
    {
        $auth = new Auth();
        $user = $auth->getUser();
        $platform = $this->request->post('platform');
        $provider = $this->request->post('provider');

        $verification = $user->verification;
        if (!$verification->mobile) {
            $this->error('请先绑定手机号再进行解绑操作');
        }

        $verifyField = $platform;
        if ($platform === 'App' && $provider === 'Wechat') {
            $verifyField = 'wxOpenPlatform';
        }

        $verification->$verifyField = 0;
        $user->verification = $verification;
        $user->save();
        $userOauth = UserOauth::where([
            'platform' => $platform,
            'provider' => $provider,
            'user_id'  => $user->id
        ])->delete();
        if ($userOauth) {
            $this->success('解绑成功');
        }
        $this->error('解绑失败');
    }

    private function setUserVerification($user, $provider, $platform)
    {
        $verification = $user->verification;
        if ($platform === 'App') {
            $platform = '';
            if ($provider === 'Wechat') {
                $platform = 'wxOpenPlatform';
            } elseif ($provider === 'Alipay') {
                $platform = 'aliOpenPlatform';
            }
        }
        if ($platform !== '') {
            $verification->$platform = 1;
            $user->verification = $verification;
            $user->save();
        }
    }

}
